#include "stdafx.h"
#include "stdlib/debugger.hpp"
#include "platform.hpp"
#include <sstream>
#include <cstdlib>
#include <cstdio>
#if defined(JH_OS_WINDOWS)
	#include <Windows.h>
	#include <MMSystem.h>
#endif

namespace JHCPP
{
	namespace stdlib
	{
		bool CDebugger::isAvailable()
		{
		#if defined(_DEBUG)
		#if defined(JH_OS_WINDOWS)
			return IsDebuggerPresent() ? true : false;
		#elif defined(JH_OS_LINUX)
			return std::getenv("JH_ENABLE_DEBUGGER") ? true : false;
		#endif
		#else
			return false;
		#endif // _DEBUG
		}

		void CDebugger::message(const std::string &msg)
		{
		#if defined(_DEBUG)
			std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
			std::fputs(msg.c_str(), stderr);
			std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);

			#if defined(JH_OS_WINDOWS)
			OutputDebugStr(msg.c_str());
			OutputDebugStr("\n");
			#endif
		#endif // _DEBUG
		}

		void CDebugger::message(const std::string& msg, const char* file, int line)
		{
		#if defined(_DEBUG)
			std::ostringstream str;
			str << msg << " [in file \"" << file << "\", line " << line << "]";
			message(str.str());
		#endif
		}

		void CDebugger::enter()
		{
		#if defined(_DEBUG)
			#if defined(JH_OS_WINDOWS)
				if (isAvailable())
				{
					DebugBreak();
				}
			#elif defined(JH_OS_LINUX)
				if (isAvailable())
				{
					kill(getpid(), SIGINT);
				}
			#endif
		#endif
		}

		void CDebugger::enter(const std::string& msg)
		{
		#if defined(_DEBUG)
			message(msg);
			enter();
		#endif
		}

		void CDebugger::enter(const std::string& msg, const char* file, int line)
		{
		#if defined(_DEBUG)
			message(msg, file, line);
			enter();
		#endif
		}

		void CDebugger::enter(const char* file, int line)
		{
		#if defined(_DEBUG)
			message("BREAK", file, line);
			enter();
		#endif
		}

	}//end of namespace stdlib
}//end of namespace JHCPP